const express = require('express')
const http = require('http')
const socketio = require('socket.io')

const port = 3000
const app = express()
const server = http.createServer(app)
const io = socketio(server)

server.listen(port, ()=> {
  console.log('server running on port 3000.');
})

app.get('/', (req, res) => {
  res.send('hello nodejs.')
})

const user2socket = {}
const socket2user = {}
let currGame = {
  success: false,
  holder: '',
  answer: '',
  lines: []
}

io.on('connection', (socket) => {

  console.log('user %s connected.', socket.id);

  // 问候语
  socket.on('sayHello', (user, fn) => {
    fn('hello ' + user.name)
  })

  // 校验昵称是否存在
  socket.on('checkUserExist', (nickname, fn) => {
    // 校验user2socket对象中是否存在该昵称,并共同回调方法返回结果
    // !!表示逻辑与的取反运算，变量值为null,'',undefined时，得到的结果为false
    fn(!!user2socket[nickname])
  })

  // 进入房间
  socket.on('enterRoom', (nickname) => {

    // 添加用户信息
    user2socket[nickname] = socket.id
    socket2user[socket.id] =  nickname

    // 发送玩家列表给当前用户
    socket.emit('roomInfo', {
      nicknames: Object.keys(user2socket),
      holder: currGame?.holder,
      
    }),

    /**
     * socket.emit() 向当前建立连接的客户端广播
     * socket.broadcast.emit() 向除建立连接之外的客户端进行广播
     * io.sockets.emit() 向所有的客户端进行广播
     */
    // 发送欢迎提示信息给所有玩家
    io.sockets.emit('userEnter', nickname)
  }),

  // 离开游戏
  socket.on('exitGame', () => {
    
    let sid = socket.id
    let nickname = socket2user[sid]
    delete socket2user[sid]
    delete user2socket[nickname]

    // 主持人离开，游戏终止

    // 发送离开的用户信息给其他人
    socket.broadcast.emit('userLeave', nickname)

    // 打印监听日志
    console.log('user %s disconnect.', socket.id)
  }),

  // 通知其他玩家开始画图
  socket.on('newLine', (line) => {
    if (currGame?.lines) {
      currGame.lines.push(line)
      socket.broadcast.emit('newLineCallback', line)
    }
  }),

  // 通知其他玩家开始更新画线
  socket.on('updateLine', (lastLine) => {
    // currGame?.lines 等价于 currGame && currGame.lines
    if (currGame?.lines) {
      currGame.lines[currGame.lines.length - 1] = lastLine
      socket.broadcast.emit('updateLineCallback', lastLine)
    }
  })

  // 断开连接
  socket.on('disconnect', () => {
    
    let sid = socket.id
    let nickname = socket2user[sid]
    delete socket2user[sid]
    delete user2socket[nickname]

    // 主持人离开，游戏终止

    // 发送离开的用户信息给其他人
    socket.broadcast.emit('userLeave', nickname)

    // 打印监听日志
    console.log('user %s disconnect.', socket.id)
  })
  
})
